home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Musique / Quod Libet / quodlibet-3.3.0-installer.exe / bin / quodlibet / qltk / prefs.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2014-12-31  |  25KB  |  596 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. from gi.repository import Gtk
  5. from quodlibet import config
  6. from quodlibet import const
  7. from quodlibet import qltk
  8. from quodlibet import util
  9. from quodlibet import app
  10. from quodlibet.config import RATINGS
  11. from quodlibet.parse import Query
  12. from quodlibet.qltk.ccb import ConfigCheckButton as CCB
  13. from quodlibet.qltk.data_editors import MultiStringEditor
  14. from quodlibet.qltk.entry import ValidatingEntry, UndoEntry
  15. from quodlibet.qltk.scanbox import ScanBox
  16. from quodlibet.qltk.maskedbox import MaskedBox
  17. from quodlibet.qltk.songlist import SongList, get_columns
  18. from quodlibet.qltk.window import UniqueWindow
  19. from quodlibet.util import copool
  20. from quodlibet.util.dprint import print_d
  21. from quodlibet.util.library import emit_signal, get_scan_dirs, scan_library
  22. from quodlibet.util import connect_obj
  23.  
  24. class PreferencesWindow(UniqueWindow):
  25.     '''The tabbed container window for the main preferences GUI.
  26.     Individual tabs are encapsulated as inner classes inheriting from `VBox`'''
  27.     
  28.     class SongList(Gtk.VBox):
  29.         name = 'songlist'
  30.         PREDEFINED_TAGS = [
  31.             ('~#disc', _('_Disc')),
  32.             ('~#track', _('_Track')),
  33.             ('grouping', _('Grou_ping')),
  34.             ('artist', _('_Artist')),
  35.             ('album', _('Al_bum')),
  36.             ('title', util.tag('title')),
  37.             ('genre', _('_Genre')),
  38.             ('date', _('_Date')),
  39.             ('~basename', _('_Filename')),
  40.             ('~#length', _('_Length')),
  41.             ('~rating', _('_Rating')),
  42.             ('~#filesize', util.tag('~#filesize'))]
  43.         
  44.         def __init__(self):
  45.             super(PreferencesWindow.SongList, self).__init__(spacing = 12)
  46.             self.set_border_width(12)
  47.             self.title = _('Song List')
  48.             vbox = Gtk.VBox(spacing = 6)
  49.             c = CCB(_('_Jump to playing song automatically'), 'settings', 'jump', populate = True, tooltip = _('When the playing song changes, scroll to it in the song list'))
  50.             vbox.pack_start(c, False, True, 0)
  51.             frame = qltk.Frame(_('Behavior'), child = vbox)
  52.             self.pack_start(frame, False, True, 0)
  53.             vbox = Gtk.VBox(spacing = 12)
  54.             buttons = { }
  55.             table = Gtk.Table.new(3, 3, True)
  56.             cols = get_columns()
  57.             for k, t in enumerate(self.PREDEFINED_TAGS):
  58.                 x = i % 3
  59.                 y = i / 3
  60.                 buttons[k] = Gtk.CheckButton(label = t, use_underline = True)
  61.                 if k in cols:
  62.                     buttons[k].set_active(True)
  63.                     cols.remove(k)
  64.                 table.attach(buttons[k], x, x + 1, y, y + 1)
  65.             
  66.             vbox.pack_start(table, False, True, 0)
  67.             if '~current' in cols:
  68.                 cols.remove('~current')
  69.             self.other_cols = cols
  70.             hbox = Gtk.HBox(spacing = 6)
  71.             l = Gtk.Label(label = _('_Others:'), use_underline = True)
  72.             hbox.pack_start(l, False, True, 0)
  73.             self.others = others = UndoEntry()
  74.             others.set_sensitive(False)
  75.             edit_button = Gtk.Button(label = _('_Edit...'), use_underline = True)
  76.             edit_button.connect('clicked', self._SongList__config_cols)
  77.             edit_button.set_tooltip_text(_('Add or remove additional column headers'))
  78.             l.set_mnemonic_widget(edit_button)
  79.             l.set_use_underline(True)
  80.             hbox.pack_start(others, True, True, 0)
  81.             hbox.pack_start(edit_button, False, True, 0)
  82.             vbox.pack_start(hbox, False, True, 0)
  83.             frame = qltk.Frame(_('Visible Columns'), child = vbox)
  84.             self.pack_start(frame, False, True, 0)
  85.             tiv = Gtk.CheckButton(label = _('Title includes _version'), use_underline = True)
  86.             aio = Gtk.CheckButton(label = _('Artist includes all _people'), use_underline = True)
  87.             aip = Gtk.CheckButton(label = _('Album includes _disc subtitle'), use_underline = True)
  88.             fip = Gtk.CheckButton(label = _('Filename includes _folder'), use_underline = True)
  89.             self._toggle_data = [
  90.                 (tiv, 'title', '~title~version'),
  91.                 (aip, 'album', '~album~discsubtitle'),
  92.                 (fip, '~basename', '~filename'),
  93.                 (aio, 'artist', '~people')]
  94.             for check, off, on in self._toggle_data:
  95.                 if on in cols:
  96.                     buttons[off].set_active(True)
  97.                     check.set_active(True)
  98.                     cols.remove(on)
  99.                     continue
  100.             others.set_text(', '.join(cols))
  101.             t = Gtk.Table.new(2, 2, True)
  102.             t.attach(tiv, 0, 1, 0, 1)
  103.             t.attach(aip, 0, 1, 1, 2)
  104.             t.attach(aio, 1, 2, 0, 1)
  105.             t.attach(fip, 1, 2, 1, 2)
  106.             frame = qltk.Frame(_('Column Preferences'), child = t)
  107.             self.pack_start(frame, False, True, 0)
  108.             vbox = Gtk.VBox(spacing = 12)
  109.             apply = Gtk.Button(stock = Gtk.STOCK_APPLY)
  110.             apply.set_tooltip_text(_('Apply current configuration to song list, adding new columns to the end'))
  111.             b = Gtk.HButtonBox()
  112.             b.set_layout(Gtk.ButtonBoxStyle.END)
  113.             b.pack_start(apply, True, True, 0)
  114.             vbox.pack_start(b, True, True, 0)
  115.             self.pack_start(vbox, True, True, 0)
  116.             apply.connect('clicked', self._SongList__apply, buttons, tiv, aip, fip, aio)
  117.             self.connect('destroy', self._SongList__apply, buttons, tiv, aip, fip, aio)
  118.             for child in self.get_children():
  119.                 child.show_all()
  120.             
  121.  
  122.         
  123.         def __apply(self, button, buttons, tiv, aip, fip, aio):
  124.             new_headers = set()
  125.             for key, name in self.PREDEFINED_TAGS:
  126.                 if buttons[key].get_active():
  127.                     new_headers.add(key)
  128.                     continue
  129.             new_headers.update(set(self.other_cols))
  130.             on_to_off = dict((lambda .0: pass)(self._toggle_data))
  131.             result = []
  132.             cur_cols = get_columns()
  133.             for h in cur_cols:
  134.                 if h in new_headers:
  135.                     result.append(h)
  136.                     continue
  137.                 
  138.                 try:
  139.                     alternative = on_to_off[h]
  140.                     if alternative in new_headers:
  141.                         result.append(alternative)
  142.                 continue
  143.                 except KeyError:
  144.                     continue
  145.                 
  146.  
  147.             
  148.             result.extend(new_headers - set(result))
  149.             for check, off, on in self._toggle_data:
  150.                 if check.get_active():
  151.                     
  152.                     try:
  153.                         result[result.index(off)] = on
  154.                     except ValueError:
  155.                         pass
  156.                     
  157.  
  158.             SongList.set_all_column_headers(result)
  159.  
  160.         
  161.         def __config_cols(self, button):
  162.             
  163.             def _SongList__closed(widget):
  164.                 self.other_cols = widget.get_strings()
  165.                 self.others.set_text(', '.join(self.other_cols))
  166.  
  167.             m = MultiStringEditor(_('Extra Columns'), self.other_cols)
  168.             m.connect('destroy', _SongList__closed)
  169.             m.show()
  170.  
  171.  
  172.     
  173.     class Browsers(Gtk.VBox):
  174.         name = 'browser'
  175.         
  176.         def __init__(self):
  177.             super(PreferencesWindow.Browsers, self).__init__(spacing = 12)
  178.             self.set_border_width(12)
  179.             self.title = _('Browsers')
  180.             vb = Gtk.VBox(spacing = 6)
  181.             hb = Gtk.HBox(spacing = 6)
  182.             l = Gtk.Label(label = _('_Global filter:'))
  183.             l.set_use_underline(True)
  184.             e = ValidatingEntry(Query.is_valid_color)
  185.             e.set_text(config.get('browsers', 'background'))
  186.             e.connect('changed', self._entry, 'background', 'browsers')
  187.             e.set_tooltip_text(_('Apply this query in addition to all others'))
  188.             l.set_mnemonic_widget(e)
  189.             hb.pack_start(l, False, True, 0)
  190.             hb.pack_start(e, True, True, 0)
  191.             vb.pack_start(hb, False, True, 0)
  192.             f = qltk.Frame(Q_('heading|Search'), child = vb)
  193.             self.pack_start(f, False, True, 0)
  194.             vb = Gtk.VBox(spacing = 6)
  195.             c1 = CCB(_('Confirm _multiple ratings'), 'browsers', 'rating_confirm_multiple', populate = True, tooltip = _('Ask for confirmation before changing the rating of multiple songs at once'))
  196.             c2 = CCB(_('Enable _one-click ratings'), 'browsers', 'rating_click', populate = True, tooltip = _('Enable rating by clicking on the rating column in the song list'))
  197.             vbox = Gtk.VBox(spacing = 6)
  198.             vbox.pack_start(c1, False, True, 0)
  199.             vbox.pack_start(c2, False, True, 0)
  200.             f = qltk.Frame(_('Ratings'), child = vbox)
  201.             self.pack_start(f, False, True, 0)
  202.             vb = Gtk.VBox(spacing = 6)
  203.             c = CCB(_('_Use rounded corners on thumbnails'), 'albumart', 'round', populate = True, tooltip = _('Round the corners of album artwork thumbnail images.'))
  204.             c.connect('toggled', self._Browsers__toggle_round_corners)
  205.             vb.pack_start(c, False, True, 0)
  206.             cb = CCB(_('Prefer _embedded art'), 'albumart', 'prefer_embedded', populate = True, tooltip = _('Choose to use artwork embedded in the audio (where available) over other sources'))
  207.             vb.pack_start(cb, False, True, 0)
  208.             hb = Gtk.HBox(spacing = 3)
  209.             cb = CCB(_('_Fixed image filename:'), 'albumart', 'force_filename', populate = True, tooltip = _('The single image filename to use if selected'))
  210.             hb.pack_start(cb, False, True, 0)
  211.             entry = UndoEntry()
  212.             entry.set_tooltip_text(_('The album art image file to use when forced'))
  213.             entry.set_text(config.get('albumart', 'filename'))
  214.             entry.connect('changed', self._Browsers__changed_text, 'filename')
  215.             entry.set_sensitive(cb.get_active())
  216.             cb.connect('toggled', self._Browsers__toggled_force_filename, entry)
  217.             hb.pack_start(entry, True, True, 0)
  218.             vb.pack_start(hb, False, True, 0)
  219.             f = qltk.Frame(_('Album Art'), child = vb)
  220.             self.pack_start(f, False, True, 0)
  221.             for child in self.get_children():
  222.                 child.show_all()
  223.             
  224.  
  225.         
  226.         def __changed_text(self, entry, name):
  227.             config.set('albumart', name, entry.get_text())
  228.  
  229.         
  230.         def __toggle_round_corners(self, *args):
  231.             qltk.redraw_all_toplevels(self)
  232.  
  233.         
  234.         def __toggled_force_filename(self, cb, fn_entry):
  235.             fn_entry.set_sensitive(cb.get_active())
  236.  
  237.         
  238.         def _entry(self, entry, name, section = 'settings'):
  239.             config.set(section, name, entry.get_text())
  240.  
  241.  
  242.     
  243.     class Player(Gtk.VBox):
  244.         name = 'playback'
  245.         
  246.         def __init__(self):
  247.             super(PreferencesWindow.Player, self).__init__(spacing = 12)
  248.             self.set_border_width(12)
  249.             self.title = _('Playback')
  250.             if app.player and hasattr(app.player, 'PlayerPreferences'):
  251.                 player_prefs = app.player.PlayerPreferences()
  252.                 f = qltk.Frame(_('Output Configuration'), child = player_prefs)
  253.                 self.pack_start(f, False, True, 0)
  254.             fallback_gain = config.getfloat('player', 'fallback_gain', 0)
  255.             adj = Gtk.Adjustment.new(fallback_gain, -12, 12, 0.5, 0.5, 0)
  256.             fb_spin = Gtk.SpinButton(adjustment = adj)
  257.             fb_spin.set_digits(1)
  258.             fb_spin.connect('changed', self._Player__changed, 'player', 'fallback_gain')
  259.             fb_spin.set_tooltip_text(_('If no Replay Gain information is available for a song, scale the volume by this value'))
  260.             fb_label = Gtk.Label(label = _('_Fall-back gain (dB):'))
  261.             fb_label.set_use_underline(True)
  262.             fb_label.set_mnemonic_widget(fb_spin)
  263.             pre_amp_gain = config.getfloat('player', 'pre_amp_gain', 0)
  264.             adj = Gtk.Adjustment.new(pre_amp_gain, -6, 6, 0.5, 0.5, 0)
  265.             adj.connect('value-changed', self._Player__changed, 'player', 'pre_amp_gain')
  266.             pre_spin = Gtk.SpinButton(adjustment = adj)
  267.             pre_spin.set_digits(1)
  268.             pre_spin.set_tooltip_text(_('Scale volume for all songs by this value, as long as the result will not clip'))
  269.             pre_label = Gtk.Label(label = _('_Pre-amp gain (dB):'))
  270.             pre_label.set_use_underline(True)
  271.             pre_label.set_mnemonic_widget(pre_spin)
  272.             widgets = [
  273.                 pre_label,
  274.                 pre_spin,
  275.                 fb_label,
  276.                 fb_spin]
  277.             c = CCB(_('_Enable Replay Gain volume adjustment'), 'player', 'replaygain', populate = True)
  278.             c.connect('toggled', self._Player__toggled_gain, widgets)
  279.             table = Gtk.Table.new(3, 2, False)
  280.             table.set_col_spacings(6)
  281.             table.set_row_spacings(6)
  282.             table.attach(c, 0, 2, 0, 1)
  283.             fb_label.set_alignment(0, 0.5)
  284.             table.attach(fb_label, 0, 1, 1, 2, xoptions = Gtk.AttachOptions.FILL)
  285.             pre_label.set_alignment(0, 0.5)
  286.             table.attach(pre_label, 0, 1, 2, 3, xoptions = Gtk.AttachOptions.FILL)
  287.             fb_align = Gtk.Alignment.new(0, 0.5, 0, 1)
  288.             fb_align.add(fb_spin)
  289.             table.attach(fb_align, 1, 2, 1, 2)
  290.             pre_align = Gtk.Alignment.new(0, 0.5, 0, 1)
  291.             pre_align.add(pre_spin)
  292.             table.attach(pre_align, 1, 2, 2, 3)
  293.             f = qltk.Frame(_('Replay Gain Volume Adjustment'), child = table)
  294.             c.emit('toggled')
  295.             self.pack_start(f, False, True, 0)
  296.             for child in self.get_children():
  297.                 child.show_all()
  298.             
  299.  
  300.         
  301.         def __toggled_gain(self, activator, widgets):
  302.             if app.player:
  303.                 app.player.volume = app.player.volume
  304.             for widget in widgets:
  305.                 widget.set_sensitive(activator.get_active())
  306.             
  307.  
  308.         
  309.         def __changed(self, adj, section, name):
  310.             config.set(section, name, str(adj.get_value()))
  311.             app.player.volume = app.player.volume
  312.  
  313.  
  314.     
  315.     class Tagging(Gtk.VBox):
  316.         name = 'tagging'
  317.         
  318.         def ratings_vbox(self):
  319.             '''Returns a new VBox containing all ratings widgets'''
  320.             vb = Gtk.VBox(spacing = 6)
  321.             model = Gtk.ListStore(float)
  322.             default_combo = Gtk.ComboBox(model = model)
  323.             default_lab = Gtk.Label(label = _('_Default rating:'))
  324.             default_lab.set_use_underline(True)
  325.             default_lab.set_alignment(0, 0.5)
  326.             
  327.             def draw_rating(column, cell, model, it, data):
  328.                 num = model[it][0]
  329.                 text = '%0.2f: %s' % (num, util.format_rating(num))
  330.                 cell.set_property('text', text)
  331.  
  332.             
  333.             def default_rating_changed(combo, model):
  334.                 it = combo.get_active_iter()
  335.                 if it is None:
  336.                     return None
  337.                 RATINGS.default = None[it][0]
  338.                 qltk.redraw_all_toplevels(self)
  339.  
  340.             
  341.             def populate_default_rating_model(combo, num):
  342.                 model = combo.get_model()
  343.                 model.clear()
  344.                 deltas = []
  345.                 default = RATINGS.default
  346.                 precision = RATINGS.precision
  347.                 for i in range(0, num + 1):
  348.                     r = i * precision
  349.                     model.append(row = [
  350.                         r])
  351.                     deltas.append((abs(default - r), i))
  352.                 
  353.                 active = sorted(deltas)[0][1]
  354.                 print_d('Choosing #%d (%.2f), closest to current %.2f' % (active, precision * active, default))
  355.                 combo.set_active(active)
  356.  
  357.             cell = Gtk.CellRendererText()
  358.             default_combo.pack_start(cell, True)
  359.             default_combo.set_cell_data_func(cell, draw_rating, None)
  360.             default_combo.connect('changed', default_rating_changed, model)
  361.             default_lab.set_mnemonic_widget(default_combo)
  362.             
  363.             def refresh_default_combo(num):
  364.                 populate_default_rating_model(default_combo, num)
  365.  
  366.             model = Gtk.ListStore(int)
  367.             scale_combo = Gtk.ComboBox(model = model)
  368.             scale_lab = Gtk.Label(label = _('Rating _Scale:'))
  369.             scale_lab.set_use_underline(True)
  370.             scale_lab.set_mnemonic_widget(scale_combo)
  371.             cell = Gtk.CellRendererText()
  372.             scale_combo.pack_start(cell, False)
  373.             num = RATINGS.number
  374.             for i in [
  375.                 1,
  376.                 2,
  377.                 3,
  378.                 4,
  379.                 5,
  380.                 6,
  381.                 8,
  382.                 10]:
  383.                 it = model.append(row = [
  384.                     i])
  385.                 if i == num:
  386.                     scale_combo.set_active_iter(it)
  387.                     continue
  388.             
  389.             def draw_rating_scale(column, cell, model, it, data):
  390.                 num_stars = model[it][0]
  391.                 text = '%d: %s' % (num_stars, RATINGS.full_symbol * num_stars)
  392.                 cell.set_property('text', text)
  393.  
  394.             
  395.             def rating_scale_changed(combo, model):
  396.                 it = combo.get_active_iter()
  397.                 if it is None:
  398.                     return None
  399.                 RATINGS.number = num = None[it][0]
  400.                 refresh_default_combo(num)
  401.  
  402.             refresh_default_combo(RATINGS.number)
  403.             scale_combo.set_cell_data_func(cell, draw_rating_scale, None)
  404.             scale_combo.connect('changed', rating_scale_changed, model)
  405.             default_align = Gtk.Alignment(xalign = 0, xscale = 0)
  406.             default_align.add(default_lab)
  407.             default_combo_align = Gtk.Alignment(xalign = 0, xscale = 0)
  408.             default_combo_align.add(default_combo)
  409.             scale_align = Gtk.Alignment(xalign = 0, xscale = 0)
  410.             scale_align.add(scale_lab)
  411.             grid = Gtk.Grid(column_spacing = 6, row_spacing = 6)
  412.             grid.add(scale_align)
  413.             grid.add(scale_combo)
  414.             grid.attach(default_align, 0, 1, 1, 1)
  415.             grid.attach(default_combo_align, 1, 1, 1, 1)
  416.             vb.pack_start(grid, False, False, 6)
  417.             bayesian_factor = config.getfloat('settings', 'bayesian_rating_factor', 0)
  418.             adj = Gtk.Adjustment.new(bayesian_factor, 0, 10, 0.5, 0.5, 0)
  419.             bayes_spin = Gtk.SpinButton(adjustment = adj, numeric = True)
  420.             bayes_spin.set_digits(1)
  421.             bayes_spin.connect('changed', self._Tagging__changed_and_signal_library, 'settings', 'bayesian_rating_factor')
  422.             bayes_spin.set_tooltip_text(_('Bayesian Average factor (C) for aggregated ratings.\n0 means a conventional average, higher values mean that albums with few tracks will have less extreme ratings. Changing this value triggers a re-calculation for all albums.'))
  423.             bayes_label = Gtk.Label(label = _('_Bayesian averaging amount:'))
  424.             bayes_label.set_use_underline(True)
  425.             bayes_label.set_mnemonic_widget(bayes_spin)
  426.             hb = Gtk.HBox(spacing = 6)
  427.             hb.pack_start(bayes_label, False, True, 0)
  428.             hb.pack_start(bayes_spin, False, True, 0)
  429.             vb.pack_start(hb, True, True, 0)
  430.             cb = CCB(_('Save ratings and play _counts'), 'editing', 'save_to_songs', populate = True)
  431.             vb.pack_start(cb, True, True, 0)
  432.             hb = Gtk.HBox(spacing = 6)
  433.             lab = Gtk.Label(label = _('_Email:'))
  434.             entry = UndoEntry()
  435.             entry.set_tooltip_text(_('Ratings and play counts will be set for this email address'))
  436.             entry.set_text(config.get('editing', 'save_email'))
  437.             entry.connect('changed', self._Tagging__changed, 'editing', 'save_email')
  438.             hb.pack_start(lab, False, True, 0)
  439.             hb.pack_start(entry, True, True, 0)
  440.             lab.set_mnemonic_widget(entry)
  441.             lab.set_use_underline(True)
  442.             vb.pack_start(hb, True, True, 0)
  443.             return vb
  444.  
  445.         
  446.         def tag_editing_vbox(self):
  447.             '''Returns a new VBox containing all tag editing widgets'''
  448.             vbox = Gtk.VBox(spacing = 6)
  449.             cb = CCB(_('Auto-save tag changes'), 'editing', 'auto_save_changes', populate = True, tooltip = _('Save changes to tags without confirmation when editing multiple files'))
  450.             vbox.pack_start(cb, False, True, 0)
  451.             hb = Gtk.HBox(spacing = 6)
  452.             e = UndoEntry()
  453.             e.set_text(config.get('editing', 'split_on'))
  454.             e.connect('changed', self._Tagging__changed, 'editing', 'split_on')
  455.             e.set_tooltip_text(_('A list of separators to use when splitting tag values. The list is space-separated'))
  456.             
  457.             def do_revert_split(button, section, option):
  458.                 config.reset(section, option)
  459.                 e.set_text(config.get(section, option))
  460.  
  461.             split_revert = Gtk.Button()
  462.             split_revert.add(Gtk.Image.new_from_stock(Gtk.STOCK_REVERT_TO_SAVED, Gtk.IconSize.MENU))
  463.             split_revert.connect('clicked', do_revert_split, 'editing', 'split_on')
  464.             l = Gtk.Label(label = _('Split _on:'))
  465.             l.set_use_underline(True)
  466.             l.set_mnemonic_widget(e)
  467.             hb.pack_start(l, False, True, 0)
  468.             hb.pack_start(e, True, True, 0)
  469.             hb.pack_start(split_revert, False, True, 0)
  470.             vbox.pack_start(hb, False, True, 0)
  471.             return vbox
  472.  
  473.         
  474.         def __init__(self):
  475.             super(PreferencesWindow.Tagging, self).__init__(spacing = 12)
  476.             self.set_border_width(12)
  477.             self.title = _('Tags')
  478.             self._songs = []
  479.             f = qltk.Frame(_('Tag Editing'), child = self.tag_editing_vbox())
  480.             self.pack_start(f, False, True, 0)
  481.             f = qltk.Frame(_('Ratings'), child = self.ratings_vbox())
  482.             self.pack_start(f, False, True, 0)
  483.             for child in self.get_children():
  484.                 child.show_all()
  485.             
  486.  
  487.         
  488.         def __changed(self, entry, section, name):
  489.             config.set(section, name, entry.get_text())
  490.  
  491.         
  492.         def __changed_and_signal_library(self, entry, section, name):
  493.             config.set(section, name, str(entry.get_value()))
  494.             print_d('Signalling "changed" to entire library. Hold tight...')
  495.             if not self._songs:
  496.                 pass
  497.             self._songs = app.library.values()
  498.             copool.add(emit_signal, self._songs, funcid = 'library changed', name = _('Updating for new ratings'))
  499.  
  500.  
  501.     
  502.     class Library(Gtk.VBox):
  503.         name = 'library'
  504.         
  505.         def __init__(self):
  506.             super(PreferencesWindow.Library, self).__init__(spacing = 12)
  507.             self.set_border_width(12)
  508.             self.title = _('Library')
  509.             cb = CCB(_('_Refresh library on start'), 'library', 'refresh_on_start', populate = True)
  510.             scan_dirs = ScanBox()
  511.             vb3 = Gtk.VBox(spacing = 6)
  512.             vb3.pack_start(scan_dirs, True, True, 0)
  513.             
  514.             def refresh_cb(button):
  515.                 scan_library(app.library, force = False)
  516.  
  517.             refresh = qltk.Button(_('Re_fresh Library'), Gtk.STOCK_REFRESH)
  518.             refresh.connect('clicked', refresh_cb)
  519.             refresh.set_tooltip_text(_('Check for changes in your library'))
  520.             
  521.             def reload_cb(button):
  522.                 scan_library(app.library, force = True)
  523.  
  524.             reload_ = qltk.Button(_('Re_load Library'), Gtk.STOCK_REFRESH)
  525.             reload_.connect('clicked', reload_cb)
  526.             reload_.set_tooltip_text(_('Reload all songs in your library. This can take a long time.'))
  527.             grid = Gtk.Grid(column_spacing = 6, row_spacing = 6)
  528.             cb.props.hexpand = True
  529.             grid.attach(cb, 0, 0, 1, 1)
  530.             grid.attach(refresh, 1, 0, 1, 1)
  531.             grid.attach(reload_, 1, 1, 1, 1)
  532.             vb3.pack_start(grid, False, True, 0)
  533.             f = qltk.Frame(_('Scan Directories'), child = vb3)
  534.             self.pack_start(f, False, True, 0)
  535.             if app.library is not None:
  536.                 masked = MaskedBox(app.library)
  537.                 f = qltk.Frame(_('Hidden Songs'), child = masked)
  538.                 self.pack_start(f, False, True, 0)
  539.             for child in self.get_children():
  540.                 child.show_all()
  541.             
  542.  
  543.  
  544.     
  545.     def __init__(self, parent):
  546.         if self.is_not_unique():
  547.             return None
  548.         None(PreferencesWindow, self).__init__()
  549.         self.current_scan_dirs = get_scan_dirs()
  550.         self.set_title(_('Preferences') + ' - Quod Libet')
  551.         self.set_resizable(False)
  552.         self.set_transient_for(qltk.get_top_parent(parent))
  553.         self._PreferencesWindow__notebook = notebook = qltk.Notebook()
  554.         for Page in [
  555.             self.SongList,
  556.             self.Browsers,
  557.             self.Player,
  558.             self.Library,
  559.             self.Tagging]:
  560.             notebook.append_page(Page())
  561.         
  562.         close = Gtk.Button(stock = Gtk.STOCK_CLOSE)
  563.         connect_obj(close, 'clicked', (lambda x: x.destroy()), self)
  564.         button_box = Gtk.HButtonBox()
  565.         button_box.set_layout(Gtk.ButtonBoxStyle.END)
  566.         button_box.pack_start(close, True, True, 0)
  567.         self.use_header_bar()
  568.         if self.has_close_button():
  569.             self.set_border_width(0)
  570.             notebook.set_show_border(False)
  571.             self.add(notebook)
  572.         else:
  573.             self.set_border_width(12)
  574.             vbox = Gtk.VBox(spacing = 12)
  575.             vbox.pack_start(notebook, True, True, 0)
  576.             vbox.pack_start(button_box, False, True, 0)
  577.             self.add(vbox)
  578.         connect_obj(self, 'destroy', PreferencesWindow._PreferencesWindow__destroy, self)
  579.         self.get_child().show_all()
  580.  
  581.     
  582.     def set_page(self, name):
  583.         notebook = self._PreferencesWindow__notebook
  584.         for p in range(notebook.get_n_pages()):
  585.             if notebook.get_nth_page(p).name == name:
  586.                 notebook.set_current_page(p)
  587.                 continue
  588.  
  589.     
  590.     def __destroy(self):
  591.         config.write(const.CONFIG)
  592.         if self.current_scan_dirs != get_scan_dirs():
  593.             scan_library(app.library, force = False)
  594.  
  595.  
  596.